#include "stdafx.h"
#include "win_console.h"


_SSL_BEGIN
_SSWINOSL_BEGIN

bool console_clear_screen()
{
	HANDLE out_handle = ::GetStdHandle(STD_OUTPUT_HANDLE);
	if(out_handle == NULL)
		return false;

	CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info = {0};
	COORD pos = {0, 0};
	DWORD number_of_writen_chars = 0;
	if(!::GetConsoleScreenBufferInfo(out_handle, &screen_buffer_info))
		return false;

	::FillConsoleOutputCharacter(out_handle, _T(''),
		screen_buffer_info.dwSize.X * screen_buffer_info.dwSize.Y,
		pos, &number_of_writen_chars);
	::FillConsoleOutputAttribute(out_handle, screen_buffer_info.wAttributes,
		screen_buffer_info.dwSize.X * screen_buffer_info.dwSize.Y,
		pos, &number_of_writen_chars);
	SetConsoleCursorPosition(out_handle, pos);

	return true;
}

bool console_set_fore_color(int color)
{
	HANDLE out_handle = ::GetStdHandle(STD_OUTPUT_HANDLE);
	if(out_handle == NULL)
		return false;

	CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info = {0};
	if(!::GetConsoleScreenBufferInfo(out_handle, &screen_buffer_info))
		return false;

	WORD attirbute = (WORD)((screen_buffer_info.wAttributes & 0xF0) + (color & 0x0F));
	return ::SetConsoleTextAttribute(out_handle, attirbute) ? true : false;
}

bool console_set_background_color(int color)
{
	HANDLE out_handle = ::GetStdHandle(STD_OUTPUT_HANDLE);
	if(out_handle == NULL)
		return false;

	CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info = {0};
	if(!::GetConsoleScreenBufferInfo(out_handle, &screen_buffer_info))
		return false;

	WORD attirbute = (screen_buffer_info.wAttributes & 0x0F) + ((color & 0x0F) << 4);
	return ::SetConsoleTextAttribute(out_handle, attirbute) ? true : false;
}

bool console_set_color(int fore_color, int background_color)
{
	WORD color = ((background_color & 0x0F) << 4) + (fore_color & 0x0F);
	return ::SetConsoleTextAttribute(::GetStdHandle(STD_OUTPUT_HANDLE), color) ? true : false;
}

bool console_get_cursor_position(int &x, int &y)
{
	HANDLE out_handle = ::GetStdHandle(STD_OUTPUT_HANDLE);
	if(out_handle == NULL)
		return false;

	CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info = {0};
	COORD pos = {0, 0};
	DWORD number_of_writen_chars = 0;
	if(!::GetConsoleScreenBufferInfo(out_handle, &screen_buffer_info))
		return false;

	x = screen_buffer_info.dwCursorPosition.X;
	y = screen_buffer_info.dwCursorPosition.Y;
	return true;
}

bool console_cursor_goto(int x, int y)
{
	HANDLE out_handle = ::GetStdHandle(STD_OUTPUT_HANDLE);
	if(out_handle == NULL)
		return false;
	COORD position = { x, y };
	return ::SetConsoleCursorPosition(out_handle, position) ? true : false;
}

bool console_cursor_move(int x_offset, int y_offset)
{
	HANDLE out_handle = ::GetStdHandle(STD_OUTPUT_HANDLE);
	if(out_handle == NULL)
		return false;

	CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info = {0};
	COORD pos = {0, 0};
	DWORD number_of_writen_chars = 0;
	if(!::GetConsoleScreenBufferInfo(out_handle, &screen_buffer_info))
		return false;

	return console_cursor_goto(screen_buffer_info.dwCursorPosition.X + x_offset,
		screen_buffer_info.dwCursorPosition.Y + y_offset);
}

bool console_fill(tchar ch, int len)
{
	HANDLE out_handle = ::GetStdHandle(STD_OUTPUT_HANDLE);
	if(out_handle == NULL)
		return false;

	CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info = {0};
	COORD pos = {0, 0};
	DWORD number_of_writen_chars = 0;
	if(!::GetConsoleScreenBufferInfo(out_handle, &screen_buffer_info))
		return false;

	if(len == -1)
	{
		len = screen_buffer_info.srWindow.Right - screen_buffer_info.dwCursorPosition.X;
	}else if(len == -2)
	{
		len = screen_buffer_info.srWindow.Right * screen_buffer_info.srWindow.Bottom - 
			(screen_buffer_info.dwCursorPosition.Y * (screen_buffer_info.srWindow.Right - screen_buffer_info.srWindow.Left + 1)
				+ screen_buffer_info.dwCursorPosition.X);
	}

	if(len < 0)
		return false;

	return ::FillConsoleOutputCharacter(out_handle, ch,
		len,
		screen_buffer_info.dwCursorPosition, &number_of_writen_chars) ? true : false;
}

_SSWINOSL_END
_SSL_END

